package com.xneure.utils.upload;

import java.io.IOException;
import java.util.Arrays;
import javax.servlet.http.HttpServletRequest;
import org.apache.commons.io.IOUtils;

public class PartFileResolver{
	private int contentLength;
	private byte[] boundary;
	private int preIndex = 0;
	private int endIndex = 0;
	private byte[] baryData;

	public PartFileResolver(HttpServletRequest req){
		contentLength = req.getContentLength();
		if(isContainFile(req)){
			try{
				baryData = IOUtils.toByteArray(req.getInputStream(),contentLength);
			}catch(IOException e){
				e.printStackTrace();
			}
		}
	}

	/**
	 * 判断是否包含文件
	 * 
	 * @param req
	 * @return boolean
	 */
	private boolean isContainFile(HttpServletRequest req){
		String type = req.getContentType();
		int sindex = type.indexOf("boundary=");
		if(sindex > -1){
			sindex += "boundary=".length();
			int eindex = type.indexOf(";",sindex);
			if(eindex < 0){
				eindex = type.length();
			}
			boundary = "--".concat(type.substring(sindex,eindex)).getBytes();
			preIndex = boundary.length;
			endIndex = preIndex;
			return true;
		}
		return false;
	}

	/**
	 * 判断是否有文件
	 * 
	 * @return boolean
	 */
	public boolean hashNext(){
		if(endIndex + boundary.length < contentLength){
			endIndex = findBoundary(endIndex);
			return endIndex != -1;
		}
		return false;
	}

	/**
	 * 查找边界
	 * 
	 * @param point
	 * @return int
	 */
	private int findBoundary(int point){
		int boundaryLength = boundary.length - 1;
		next:
		for(int i = point;i < contentLength;i++){
			if(baryData[i] == boundary[0] && baryData[boundaryLength + i] == boundary[boundaryLength]){
				for(int l = 1;l < boundaryLength;l++){
					if(baryData[i + l] != boundary[boundaryLength - (boundaryLength - l)]){
						continue next;
					}
				}
				return i + boundaryLength + 1;
			}
			if(i >= baryData.length - boundaryLength - 1){
				break;
			}
		}
		return -1;
	}

	/**
	 * 获取文件
	 * 
	 * @return FileItem
	 */
	public FileItem nextFile(){
		if(endIndex != -1){
			FileItem fileItem = new FileItem(Arrays.copyOfRange(baryData,preIndex + 2,endIndex - boundary.length - 3));
			preIndex = endIndex;
			return fileItem;
		}else{
			preIndex = contentLength;
			return null;
		}
	}
}
